/*
*Copyright 2021-2023 NERCIS
*
*Licensed under the Apache License, Version 2.0 (the "License");
*you may not use this file except in compliance with the License.
*You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*Unless required by applicable law or agreed to in writing, software
*distributed under the License is distributed on an "AS IS" BASIS,
*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*See the License for the specific language governing permissions and
*limitations under the License.
*/

package cn.ac.nercis.pes.community.controller.manage;

import cn.ac.nercis.pes.community.component.cells.NumberTableCell;
import cn.ac.nercis.pes.community.component.cells.opreate.OperateTableCell;
import cn.ac.nercis.pes.community.component.controls.PesTextField;
import cn.ac.nercis.pes.community.component.dialog.*;
import cn.ac.nercis.pes.community.controller.base.InitDataLoad;
import cn.ac.nercis.pes.community.mapper.manage.TestedUnitViewMapper;
import cn.ac.nercis.pes.community.model.vo.TableDataModel;
import cn.ac.nercis.pes.community.model.vo.manage.TestedUnitVO;
import cn.ac.nercis.pes.community.support.FXMLController;
import cn.ac.nercis.pes.community.utils.IconUtils;
import cn.ac.nercis.pes.community.utils.SpringUtils;
import cn.ac.nercis.pes.community.views.manage.AddTestedUnitView;
import cn.ac.nercis.pes.model.dto.manage.TestedUnitDTO;
import cn.ac.nercis.pes.service.manage.TestedUnitService;
import javafx.application.Platform;
import javafx.collections.transformation.FilteredList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.MouseEvent;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;

import java.net.URL;
import java.util.List;
import java.util.Objects;
import java.util.ResourceBundle;
import java.util.concurrent.CompletableFuture;

/**
 * 被测单位控制器
 * @author zpy
 * @version 1.0.0
 */
@Slf4j
@FXMLController
public class TestedUnitController implements Initializable, InitDataLoad {
    @FXML
    private Label titleLabel;
    @FXML
    private TextField queryText;
    @FXML
    private Button searchButton;
    @FXML
    private Button addButton;
    @FXML
    private Pagination pagination;

    @FXML
    private TableView<TestedUnitDTO> tableView;
    @FXML
    private TableColumn<TestedUnitDTO,String> numberColumn;
    @FXML
    private TableColumn<TestedUnitDTO,String> nameColumn;
    @FXML
    private TableColumn<TestedUnitDTO,String> addressColumn;
    @FXML
    private TableColumn<TestedUnitDTO,String> postalCodeColumn;
    @FXML
    private TableColumn<TestedUnitDTO,String> manageColumn;
    @FXML
    private TableColumn<TestedUnitDTO,String> contactPersonColumn;
    @FXML
    private TableColumn<TestedUnitDTO,String> operateColumn;

    @FXML
    private PesTextField nameField;
    @FXML
    private PesTextField addressField;
    @FXML
    private PesTextField postalCodeField;
    @FXML
    private PesTextField manageField;
    @FXML
    private PesTextField contactPersonField;
    @FXML
    private PesTextField contactPositionField;
    @FXML
    private PesTextField contactDepartmentField;
    @FXML
    private PesTextField contactTelField;
    @FXML
    private PesTextField contactPhoneField;
    @FXML
    private PesTextField contactEmailField;

    private PageDialog pageDialog;

    private final TestedUnitService testedUnitService;
    private final TableDataModel<TestedUnitDTO> dataModel = new TableDataModel<>();
    private final TestedUnitVO testedUnitVO = new TestedUnitVO();

    @Autowired
    public TestedUnitController(TestedUnitService testedUnitService) {
        this.testedUnitService = testedUnitService;
    }


    @Override
    public void initialize(URL location, ResourceBundle resources) {
        titleLabel.setGraphic(IconUtils.getGlyph("tested-unit-icon","title-icon"));
        searchButton.setGraphic(IconUtils.getGlyph("search-icon","btn-icon"));
        addButton.setGraphic(IconUtils.getGlyph("add-button-icon","btn-icon"));

        numberColumn.setCellFactory(col-> new NumberTableCell<>(this.pagination));
        nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
        addressColumn.setCellValueFactory(new PropertyValueFactory<>("address"));
        postalCodeColumn.setCellValueFactory(new PropertyValueFactory<>("postalCode"));
        manageColumn.setCellValueFactory(new PropertyValueFactory<>("manage"));
        contactPersonColumn.setCellValueFactory(new PropertyValueFactory<>("contactPerson"));
        operateColumn.setCellFactory(col->new OperateTableCell<>(tableView,
                this::onEditButtonClick,this::onDelButtonClick));

        tableView.setItems(new FilteredList<>(dataModel.bodyProperty(), p->true));
        dataModel.selectedIndexProperty().bind(tableView.getSelectionModel().selectedIndexProperty());
        pagination.pageCountProperty().bind(dataModel.pageCountProperty());
        pagination.currentPageIndexProperty()
                .addListener((obj, oldValue, number) -> {
                    if(Objects.nonNull(number)){
                        query(number.intValue());
                    }
                });

        //新增、编辑被测单位控件初始化
        initTestedUnitControl();
    }

    @Override
    public void initializeData() {
        this.onSearch();
    }

    @FXML
    public void onSearch(){
        pagination.currentPageIndexProperty().setValue(0);
        query(0);
    }

    @FXML
    private void onCreate(){
        pageDialog = PageDialog.builder()
                .withIcon("dialog-edit-icon")
                .withTitle("被测单位")
                .withShowActions(false)
                .withContent(SpringUtils.getBean(AddTestedUnitView.class).getView())
                .build();
        //初始化验证信息
        resetValidation();
        //新增被测单位数据初始化
        initAddTestedUnitData();
        //弹出新增用户页面
        pageDialog.show(this::onSave);
    }

    private void onEditButtonClick(MouseEvent event) {
        TestedUnitDTO selectedUnit = dataModel.bodyProperty().get(dataModel.getSelectedIndex());
        pageDialog = PageDialog.builder()
                .withIcon("dialog-edit-icon")
                .withTitle("被测单位")
                .withShowActions(false)
                .withContent(SpringUtils.getBean(AddTestedUnitView.class).getView())
                .build();
        //初始化验证信息
        resetValidation();
        //编辑用户数据初始化
        SpringUtils.getBean(AddTestedUnitController.class).initModifyTestedUnitData(selectedUnit);
        //弹出修改被测单位
        pageDialog.show(this::onSave);
    }

    private void onDelButtonClick(MouseEvent event){
        TestedUnitDTO selectedUnit = dataModel.bodyProperty().get(dataModel.getSelectedIndex());
        AlertDialog alertDialog = AlertDialog.builder()
                .withMode(AlertMode.CONFIRM)
                .withType(AlertType.WARN)
                .withTitle("删除提示")
                .withContent("确认删除当前被测单位信息吗？")
                .build();
        alertDialog.show((confirm)->{
            if(!confirm){
                return;
            }
            deleteTestedUnit(selectedUnit.getId());
        });
    }

    private void onSave() {
        this.testedUnitVO.setName(StringUtils.trim(this.testedUnitVO.getName()));
        if (!this.nameField.validate()) {
            return;
        }
        TestedUnitDTO unitDTO = TestedUnitViewMapper.INSTANCE.toDTO(this.testedUnitVO);
        CompletableFuture.supplyAsync(() -> testedUnitService.save(unitDTO))
                .thenAccept(res -> Platform.runLater(() -> {
                    if (res.isSuccess()) {
                        //更新表数据
                        this.query(0);
                        this.pageDialog.close();
                        MessageDialog.builder()
                                .withType(MessageType.SUCCESS).withMessage("保存成功")
                                .build().show();
                    }else{
                        MessageDialog.builder()
                                .withType(MessageType.FAIL).withMessage(res.getMsg())
                                .build().show();
                    }
                }));
    }

    private void deleteTestedUnit(final String unitId){
        CompletableFuture.supplyAsync(()->testedUnitService.delete(unitId))
                .thenAccept(res->Platform.runLater(()->{
                    if(res.isSuccess()){
                        //更新表数据
                        this.query(0);
                        MessageDialog.builder()
                                .withType(MessageType.SUCCESS).withMessage("删除成功")
                                .build().show();
                    }else{
                        MessageDialog.builder()
                                .withType(MessageType.FAIL).withMessage(res.getMsg())
                                .build().show();
                    }
                }));
    }

    private void initAddTestedUnitData(){
        testedUnitVO.setId("");
        testedUnitVO.setName("");
        testedUnitVO.setAddress("");
        testedUnitVO.setPostalCode("");
        testedUnitVO.setManage("");
        testedUnitVO.setContactPerson("");
        testedUnitVO.setContactPosition("");
        testedUnitVO.setContactDepartment("");
        testedUnitVO.setContactTel("");
        testedUnitVO.setContactPhone("");
        testedUnitVO.setContactEmail("");
    }

    private void query(Integer page){
        String query = StringUtils.trim(queryText.getText());
        CompletableFuture.supplyAsync(()->this.testedUnitService.findAll(query, PageRequest.of(page,TableDataModel.LIMIT)))
                .thenAccept(res-> Platform.runLater(()->{
                    dataModel.bodyProperty().clear();
                    List<TestedUnitDTO> testedUnits = res.getContent();
                    dataModel.setPageCount(res.getTotalPages());
                    dataModel.bodyProperty().addAll(testedUnits);
                }));
    }

    private void resetValidation(){
        this.nameField.resetValidation();
    }

    private void initTestedUnitControl(){
        //控件绑定到数据模型
        this.nameField.textProperty().bindBidirectional(testedUnitVO.nameProperty());
        this.addressField.textProperty().bindBidirectional(testedUnitVO.addressProperty());
        this.postalCodeField.textProperty().bindBidirectional(testedUnitVO.postalCodeProperty());
        this.manageField.textProperty().bindBidirectional(testedUnitVO.manageProperty());
        this.contactPersonField.textProperty().bindBidirectional(testedUnitVO.contactPersonProperty());
        this.contactPositionField.textProperty().bindBidirectional(testedUnitVO.contactPositionProperty());
        this.contactDepartmentField.textProperty().bindBidirectional(testedUnitVO.contactDepartmentProperty());
        this.contactTelField.textProperty().bindBidirectional(testedUnitVO.contactTelProperty());
        this.contactPhoneField.textProperty().bindBidirectional(testedUnitVO.contactPhoneProperty());
        this.contactEmailField.textProperty().bindBidirectional(testedUnitVO.contactEmailProperty());
    }
}